#include "../os_common.h"



//*************************************************************************************
//Implement funciton
//*************************************************************************************

VOID SendEAPoLPacket(PVOID DeviceHandle, UCHAR* Buffer, UINT BufferSize)
{
	PADAPTER Adapter=(PWB32_ADAPTER)DeviceHandle;
	PWB_STA_WPA_DESCRIPTION pWbSta = &Adapter->Global_STA_Wpa;

	 //..........................................
	//Added by WangJS 2005.11.17
	//To test, Added by WangJS 2005.11.25
#ifdef _WPA_PSK_DEBUG	
	  WBDEBUG(("Send Packet & size= %d\n",BufferSize));
	  DataDmp(Buffer, BufferSize, 0);
#endif 
	//..........................................

	// 20060802 Add
	pWbSta->Frame = Buffer;
	pWbSta->FrameSize = (USHORT)BufferSize;
	Mds_Tx( Adapter );
//	EAP_SendPacket(Adapter, Buffer, (USHORT)BufferSize);

	return;
}

VOID GetEAPoLPacket(PVOID DeviceHandle, PVOID pDes) // 20060802
{
	PADAPTER Adapter=(PWB32_ADAPTER)DeviceHandle;
	PWB_STA_WPA_DESCRIPTION pWbSta = &Adapter->Global_STA_Wpa;
	PDESCRIPTOR pDesTmp = (PDESCRIPTOR)pDes;

	DESCRIPTOR_ADD_BUFFER( pDesTmp, pWbSta->Frame, DOT_3_TYPE_OFFSET + 2 ); // 14 Byte
	DESCRIPTOR_ADD_BUFFER( pDesTmp, pWbSta->Frame + DOT_3_TYPE_OFFSET + 2, pWbSta->FrameSize - (DOT_3_TYPE_OFFSET + 2) ); // len - 14
	DESCRIPTOR_SET_TYPE( pDesTmp, FRAME_TYPE_802_3_DATA );
}

VOID GetEAPoLPacketComplete(PVOID DeviceHandle, PVOID pDes) // 20060802
{
	PADAPTER Adapter=(PWB32_ADAPTER)DeviceHandle;
	PWB_STA_WPA_DESCRIPTION pWbSta = &Adapter->Global_STA_Wpa;

	pWbSta->FrameSize = 0;
}

UINT SetAddKey(PVOID DeviceHandle, AP_802_11_KEY* KeyMaterial)
{
		PWB32_ADAPTER Adapter=(PWB32_ADAPTER)DeviceHandle;

		NDIS_802_11_KEY *p = (NDIS_802_11_KEY *)KeyMaterial;
	    UCHAR              *ptx_tsc = NULL;
    	UCHAR              *prx_tsc = NULL;
        UCHAR              key_type;
		UCHAR				key_len;
#ifdef _WPA_PSK_DEBUG
		WBDEBUG(("[4-way] ** Length   = %d\n", p->Length));
        WBDEBUG(("[4-way] ** KeyIndex = 0x%08X\n", p->KeyIndex));
        WBDEBUG(("[4-way] ** KeyLength = %d\n", p->KeyLength));
        WBDEBUG(("[4-way] ** BSSID = " MACSTR "\n", MAC2STR(p->BSSID)));
        WBDEBUG(("[4-way] ** KeyRSC (hi) = %d\n", p->KeyRSC >> 32));
        WBDEBUG(("[4-way] ** KeyRSC (lo) = %d\n", p->KeyRSC));
        DataDmp(p->KeyMaterial, p->KeyLength, 0);
#endif	
	 
		if (p->KeyIndex == 0xC0000001)
    	{
		        //StatusToReturn = NDIS_STATUS_INVALID_DATA;
				return 0;
        }
	    else
    	{	//TODO: ??Should it set encryption status for the some XP OID sequence??
					switch (p->KeyLength)
					{
						case 5:
							//WBDEBUG(("Key Type = WEP40\n"));
							key_type = HAL_KEYTYPE_WEP40;
							key_len = 5;
							//sme_set_encryption_status(Adapter, ENCRYPT_WEP);
							break;
						case 13:
							//WBDEBUG(("Key Type = WEP104\n"));
							key_type = HAL_KEYTYPE_WEP104;
							key_len = 13;
							//sme_set_encryption_status(Adapter, ENCRYPT_WEP);
							break;
						case 16:
							//WBDEBUG(("Key Type = CCMP\n"));
							key_type = HAL_KEYTYPE_AES_CCMP;
							key_len = 16;
							//sme_set_encryption_status(Adapter, ENCRYPT_CCMP);
							break;
						case 32:
							//WBDEBUG(("Key Type = TKIP\n"));
							key_type = HAL_KEYTYPE_TKIP;
							key_len = 16;
							//sme_set_encryption_status(Adapter, ENCRYPT_TKIP);
							break;
						default:
							//WBDEBUG(("Key Type = UNKNOWN\n"));
							return 0;
					}

					if (p->KeyIndex & BIT(29))
					{
						// the KeyRSC should be used to set the initial receive
						// SC for the key when BIT 29 is set to 1.

						// If the encryption cipher needs less bytes than supplied
						// by KeyRSC, the least significant bytes should be used.
						prx_tsc = (UCHAR*) &p->KeyRSC;
					}

					if (sme_add_key(Adapter,
								p->KeyIndex,
								key_len,
								key_type,
								p->BSSID,
								ptx_tsc,
								prx_tsc,
								//p->KeyRSC,
								p->KeyMaterial) == -1)
					{
						#ifdef _WPA_PSK_DEBUG
						WBDEBUG(("Install Key Fail\n"));		
						#endif
						return 0;
					}
            
	        }
/*
    	    else
        	{
            	*pBytesNeed = sizeof(NDIS_802_11_KEY);

	            
	        }
*/
	return 1;
}
/*
UINT SetDeAuthentication(PVOID DeviceHandle, MACAddress* DA, USHORT ReasonCode)
{
	return 0;
}

UINT SetDeAssocation(PVOID DeviceHandle, MACAddress* DA, USHORT ReasonCode)
{
	return 0;
}

UINT GetEAPoLPacket(PVOID DeviceHandle, STA_EAPOL_STATUS* StationPacket)
{
	return 0;
}

VOID GetBssid(PVOID DeviceHandle, UCHAR* Bssid)
{
	
	return;
}

VOID GetMACAddress(PVOID DeviceHandle, UCHAR* MACAddress)
{
	return;
}
*/
VOID GetRsnElement(PVOID DeviceHandle, UCHAR* RSN, UINT RSN_Length)
{
			NDIS_802_11_ASSOCIATION_INFORMATION *p;
            UCHAR  *pie;
            UCHAR  conn_status;

            PWB32_ADAPTER pcore_data, Adapter;
			Adapter=pcore_data = (PWB32_ADAPTER)DeviceHandle;

			p = (NDIS_802_11_ASSOCIATION_INFORMATION *) RSN;
			sme_get_connect_status(pcore_data, &conn_status);

            if (conn_status == MEDIA_STATE_CONNECTED)
            {
                p->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
                // Association Request
                p->AvailableRequestFixedIEs =
                            NDIS_802_11_AI_REQFI_CAPABILITIES |
                            NDIS_802_11_AI_REQFI_LISTENINTERVAL|
							NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;
				//p->RequestFixedIEs.Capabilities		= pcore_data->sSmePara.wCapabilityInfo;
				p->RequestFixedIEs.Capabilities =
						pcore_data->asBSSDescriptElement[pcore_data->sLocalPara.wConnectedSTAindex].CapabilityInformation.wValue;
				p->RequestFixedIEs.ListenInterval	= pcore_data->sLocalPara.ListenInterval;
				//memcpy(p->RequestFixedIEs.CurrentAPAddress,
				//		pcore_data->asBSSDescriptElement[pcore_data->sSmePara.wDesiredJoinBSS].abBssID,
				//		MAC_ADDR_LENGTH);
				OS_MEMORY_COPY(p->RequestFixedIEs.CurrentAPAddress,
						pcore_data->asBSSDescriptElement[pcore_data->sLocalPara.wConnectedSTAindex].abBssID,
						MAC_ADDR_LENGTH);

                p->RequestIELength = psSME->AssocReqVarLen;
                p->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);

                // Association Response
                p->AvailableResponseFixedIEs =
                            NDIS_802_11_AI_RESFI_CAPABILITIES |
                            NDIS_802_11_AI_RESFI_STATUSCODE |
                            NDIS_802_11_AI_RESFI_ASSOCIATIONID;
				//TODO:
                p->ResponseFixedIEs.Capabilities    = 0x0411;
                p->ResponseFixedIEs.StatusCode      = 0;
				p->ResponseFixedIEs.AssociationId	= pcore_data->sLocalPara.Association_ID&0x3fff;
			

                p->ResponseIELength = psSME->AssocRespVarLen;
                p->OffsetResponseIEs =
                            sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+
                            psSME->AssocReqVarLen;


                pie = ((UCHAR*) p) + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
				OS_MEMORY_COPY(pie, psSME->AssocReqVarIE, psSME->AssocReqVarLen);

                pie += psSME->AssocReqVarLen;
				OS_MEMORY_COPY(pie, psSME->AssocRespVarIE, psSME->AssocRespVarLen);
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("ASSOCIATION INFORMATION\n"));
                DataDmp((UCHAR *)p, p->Length+psSME->AssocReqVarLen+psSME->AssocRespVarLen, 0);
				#endif
				/*
                bytes_needed = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+
                               psSME->AssocReqVarLen+psSME->AssocRespVarLen;
				*/
			}
			else
			{
				p->Length=0;
			}
	
}


